package com.mstarc.app.mnfc;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.mstarc.app.mnfc.mstarcApiUtils.ApduUtil;
import com.mstarc.app.mnfc.mstarcApiUtils.BytetohexStringUtil;
import com.mstarc.app.mnfc.mstarcApiUtils.InitSEIDUtil;
import com.mstarc.app.mnfc.mstarcApiUtils.InitializeUtil;
import com.mstarc.app.mnfc.mstarcApiUtils.StringAndByteUtil;

import mstarc_os_api.mstarc_os_api_msg;

/**
 * @author 崔健伟
 * @version V1.0
 * @Title: TestActivity.java
 * @Package com.mstarc.app.mnfc
 * @Description:
 * @date 2017/8/18 10:51
 */
public class TestActivity extends BaseActivity implements View.OnClickListener {
    private static final String TAG = "TestActivity";
    private static final String TYPE = "&type=tc";
    private static final String FIRSTREQUESTSTR = "&start=1";
    private static final String SEID_STR = "&seId=";
    private static final String APPSERIAL = "&appSerial=";//卡号
    private static final String BALANCE = "&balance=";//余额
    private static final String CHARGECOUNT = "&chargeCount=";//充值金额
    private static final String LASTRECORD = "&lastRecord=";//最后一次交易记录
    private static final String LASTAPDU = "&lastApdu=";//最后一次请求的apdu指令
    private static final String LASTDATA = "&lastData=";
    private static final String APDUNUM = "&apduSum=";
    private static final String LASTAPDUSW = "&lastApduSw=";
    private static final int URL_TYPE_PERSONALIZE = 20001;
    private static final int URL_TYPE_KEYI = 20002;
    private static final int REQUEST_TYPE_CREATE = 30001;
    private static final int REQUEST_TYPE_DOWNLOAD = 30002;
    private static final int REQUEST_TYPE_READ = 30003;
    private static final int REQUEST_TYPE_RECHARGE = 30004;
    private static final int REQUEST_TYPE_KEYI = 30005;
    private static final int HANDLER_WHAT1 = 40001;
    private static final int HANDLER_WHAT2 = 40002;
    private static final int HANDLER_WHAT3 = 40003;
    private static final int HANDLER_WHAT4 = 40004;
    private static final int HANDLER_WHAT5 = 40005;
    private static final int HANDLER_WHAT6 = 40006;
    private static final int HANDLER_WHAT7 = 40007;
    private static final int HANDLER_WHAT8 = 40008;
    private static final int HANDLER_WHAT9 = 40009;

    private Button activity_test_create_tc_btn,
            activity_test_download_apdu_btn,
            activity_test_read_code_btn,
            activity_test_recharge_btn;
    private TextView mTextView;
    private EditText mEditText;

    private mstarc_os_api_msg m_api_msg;
    private String seid = "";
    private String URL = "";//网络请求的接口地址前缀
    private int count = 0;//记录第几次网络请求
    private int apduSum = 0;//apdu请求中9000的个数
    private String lastData = "";
    private int[] lastApduSw = new int[2];
    int[] secondApdu = new int[]{0x00, 0xc0, 0x00, 0x00, 0x00};
    private String mLastApdu = "";//每次请求执行的最后一条apdu指令
    private String mCity = "";//城市代码（TC）
    private String mCode = "";//卡号
    private String mBalance = "";//余额
    private String mChargeCount = "";//充值金额
    private String mLastRecord = "";//最后一条交易记录
    private int requestType = 0;
    private String mRecords = "";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        setTouchListener(this);
        m_api_msg = InitializeUtil.getInstance(this).getM_api_msg();
        initView();
    }

    private void initView() {
        mEditText = (EditText) findViewById(R.id.activity_test_money_et);
        mTextView = (TextView) findViewById(R.id.activity_test_info_tv);
        activity_test_create_tc_btn = (Button) findViewById(R.id.activity_test_create_tc_btn);
        activity_test_download_apdu_btn = (Button) findViewById(R.id.activity_test_download_apdu_btn);
        activity_test_read_code_btn = (Button) findViewById(R.id.activity_test_read_code_btn);
        activity_test_recharge_btn = (Button) findViewById(R.id.activity_test_recharge_btn);
        activity_test_create_tc_btn.setOnClickListener(this);
        activity_test_download_apdu_btn.setOnClickListener(this);
        activity_test_read_code_btn.setOnClickListener(this);
        activity_test_recharge_btn.setOnClickListener(this);
    }

    /**
     * 点击空白 收起键盘
     *
     * @param context
     */
    private static void setTouchListener(final Activity context) {
        context.getWindow().getDecorView().setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
                if (context.getCurrentFocus() != null) {
                    imm.hideSoftInputFromWindow(context.getCurrentFocus().getWindowToken(), 0);
                } else {
                    imm.hideSoftInputFromWindow((context.findViewById(android.R.id.content)).getWindowToken(), 0);
                }
                return false;
            }
        });
    }

    @Override
    public void onClick(View view) {
        initMstarc();
        initSEID();
        resetAllBtn(false);
        setTextShow("");
        switch (view.getId()) {
            case R.id.activity_test_create_tc_btn://创建ssd
                setTextShow(getString(R.string.creating));
                mHandler.sendEmptyMessage(HANDLER_WHAT2);
                break;
            case R.id.activity_test_download_apdu_btn://下载apdu
                setTextShow(getString(R.string.downloading));
                mHandler.sendEmptyMessage(HANDLER_WHAT3);
                break;
            case R.id.activity_test_read_code_btn://读卡
                setTextShow(getString(R.string.reading));
                mHandler.sendEmptyMessage(HANDLER_WHAT4);
                break;
            case R.id.activity_test_recharge_btn://充值
                setTextShow(getString(R.string.recharging));
                mHandler.sendEmptyMessage(HANDLER_WHAT5);
                break;
        }
    }

    private void readTextShow() {
        String showStr = "";
        if (mCity.equals("") || mCode.equals("")) {
            showStr = showStr + getString(R.string.readError) + "\n";
        }
        showStr = showStr + "城市代码：" + mCity + "\n" +
                "卡号：" + mCode + "\n" +
                "余额：" + mBalance + "\n" +
                "最后一笔充值记录：" + mLastRecord + "\n" +
                "交易记录：" + "\n" + mRecords;
        setTextShow(showStr);
    }

    private void resetAllBtn(boolean clickable) {
        activity_test_create_tc_btn.setClickable(clickable);
        activity_test_download_apdu_btn.setClickable(clickable);
        activity_test_read_code_btn.setClickable(clickable);
        activity_test_recharge_btn.setClickable(clickable);
    }

    private void setTextShow(String message) {
        mTextView.setText(message);
        resetAllBtn(true);
    }

    private void toKEYI() {
        requestType = REQUEST_TYPE_KEYI;
        getTCCode();
        toRecharge(URL_TYPE_KEYI);
    }

    private void toRecharge(int urlType) {
        if (mCity.equals("") || mCode.equals("")) {
            setTextShow(getString(R.string.readError));
            return;
        }
        String codeStr = mCity + mCode;
        if (urlType == URL_TYPE_PERSONALIZE) {
            URL = HttpUrlUtil.PERSONALIZE_URL + getRechargeStr(codeStr);
        } else {
            URL = HttpUrlUtil.KEYI_URL + getRechargeStr(codeStr);
        }
        startHttp(URL + FIRSTREQUESTSTR, 1);
    }

    private void getRechargeNum() {
        mChargeCount = mEditText.getText().toString();
    }

    private String getRechargeStr(String codeStr) {
        return APPSERIAL + codeStr + BALANCE + mBalance + CHARGECOUNT + mChargeCount + LASTRECORD + mLastRecord;
    }

    private void logIntArray(int[] intArray, String tagTitle) {
        LogUtil.logIntArray(intArray, tagTitle);
    }

    private void startLog(String logTitle, String logContent) {
        LogUtil.startLog(logTitle, logContent);
    }

    private void startToast(String message) {
        Toast.makeText(TestActivity.this, message, Toast.LENGTH_LONG).show();
    }

    private void initSEID() {
        if (seid.equals("")) {
            int[] seidResult = InitSEIDUtil.initSEID(m_api_msg);
            if (seidResult != null) {
                logIntArray(seidResult, "Code:");
                seid = StringAndByteUtil.intArrayToHexString(InitSEIDUtil.getSEID(seidResult));
                startLog("seidForHex：", seid);
            } else {
                startToast("获取SEID失败！");
            }
        }
    }

    private void initMstarc() {
        if (!InitializeUtil.getInstance(TestActivity.this).isHasConnected()) {
            m_api_msg = InitializeUtil.getInstance(TestActivity.this).getM_api_msg();
        }
        if (!InitializeUtil.getInstance(TestActivity.this).isHasInit()) {
            InitializeUtil.getInstance(TestActivity.this).init(m_api_msg);
        }
    }

    private void toCreateSSD() {
        requestType = REQUEST_TYPE_CREATE;
        URL = HttpUrlUtil.SSD_URL;
        startHttp(URL + getFirstRequest(), 1);
        setTextShow(getString(R.string.creating));
    }

    /**
     * 下载太仓的apdu包
     */
    private void downloadApduTC() {
        requestType = REQUEST_TYPE_DOWNLOAD;
        URL = HttpUrlUtil.APDU_URL;
        startHttp(URL + getFirstRequest(), 1);
    }

    /**
     * 太仓读卡
     */
    private void getTCCode() {
        /*======选择应用======*/
        mRecords = "";
        int[] params = StringAndByteUtil.getInt("00A4040010A0000005980000051200000200000001");
        int[] results = ApduUtil.apdu(m_api_msg, params);
        if (results != null)
            logIntArray(results, "chooseApp1：");
        results = is0x61(results);
        if (results != null)
            logIntArray(results, "chooseApp2：");
        if (!isSucceed(results)) {
            setTextShow(getString(R.string.readError));
            return;
        }
        params = StringAndByteUtil.getInt("00A40000023F00");
        results = ApduUtil.apdu(m_api_msg, params);
        if (results != null) {
            logIntArray(results, "file1结果1：");
        }
        results = is0x61(results);
        if (results != null) {
            logIntArray(results, "file1结果2：");
        }
        if (!isSucceed(results)) {
            setTextShow(getString(R.string.readError));
            return;
        }
        params = StringAndByteUtil.getInt("00A40000023F01");
        results = ApduUtil.apdu(m_api_msg, params);
        if (results != null) {
            logIntArray(results, "file2结果1：");
        }
        results = is0x61(results);
        if (results != null) {
            logIntArray(results, "file2结果2：");
        }
        params = StringAndByteUtil.getInt("00B0950202");
        results = ApduUtil.apdu(m_api_msg, params);
        if (results != null) {
            logIntArray(results, "选择城市结果：");
        }
        if (isSucceed(results)) {
            String cityStr = StringAndByteUtil.intArrayToHexString(results);
            mCity = cityStr.substring(0, cityStr.length() - 4);
        } else {
            return;
        }
        params = StringAndByteUtil.getInt("00B0950C08");
        results = ApduUtil.apdu(m_api_msg, params);
        if (results != null) {
            logIntArray(results, "读卡1结果：");
        }
        getFinallyCodeTC(results);
        params = StringAndByteUtil.getInt("805C000204");
        results = ApduUtil.apdu(m_api_msg, params);
        if (results != null) {
            logIntArray(results, "余额1结果：");
        }
        if (isSucceed(results)) {
            String blalanceStr = StringAndByteUtil.intArrayToHexString(results);
            mBalance = blalanceStr.substring(2, blalanceStr.length() - 4);
            mBalance = Integer.parseInt(mBalance, 16) + "";
            startLog("余额：", mBalance);
        }
        /*====================↓↓↓↓消费记录↓↓↓↓=======================*/
        params = StringAndByteUtil.getInt("00A40000020018");
        results = ApduUtil.apdu(m_api_msg, params);
        if (results != null) {
            logIntArray(results, "消费记录1结果：");
        }
        for (int i = 0x01; i <= 0x0A; i++) {
            String iStr = i + "";
            if (i < 10) {
                iStr = "0" + i;
            }
            params = StringAndByteUtil.getInt("00B2" + iStr + "0417");
            results = ApduUtil.apdu(m_api_msg, params);
            if (results != null) {
                logIntArray(results, (i + 1) + "消费记录2结果：");
            }
            getRecords(results);
            if (results.length >= 2 && results[results.length - 2] == 0x6A && results[results.length - 1] == 0x83) {
                break;
            }
        }
//        startLog("交易记录：", mRecords);
//        params = StringAndByteUtil.getInt("00A40000020010");
//        results = ApduUtil.apdu(m_api_msg, params);
//        if (results != null) {
//            logIntArray(results, "异地消费记录1结果：");
//        }
//        for (int i = 0x01; i <= 0x0A; i++) {
//            String iStr = i + "";
//            if (i < 10) {
//                iStr = "0" + i;
//            }
//            startLog("iStr：", iStr);
//            params = StringAndByteUtil.getInt("00B2" + iStr + "0417");
//            results = ApduUtil.apdu(m_api_msg, params);
//            if (results != null) {
//                logIntArray(results, (i + 1) + "异地消费记录2结果：");
//            }
//            if (results.length >= 2 && results[results.length - 2] == 0x6A && results[results.length - 1] == 0x83) {
//                break;
//            }
//        }
        /*=========================↑↑↑↑消费记录↑↑↑↑================================*/
        params = StringAndByteUtil.getInt("00A4000002001A");
        results = ApduUtil.apdu(m_api_msg, params);
        if (results != null) {
            logIntArray(results, "读取充值记录1结果：");
        }
        params = StringAndByteUtil.getInt("00B2010417");
        results = ApduUtil.apdu(m_api_msg, params);
        if (results != null) {
            logIntArray(results, "最后一条充值记录1结果：");
        }
        mLastRecord = StringAndByteUtil.intArrayToHexString(results);
        if (requestType == REQUEST_TYPE_READ) {
            getRequestType(false);
        }
    }

    private void getRecords(int[] results) {
        if (isSucceed(results)) {
            String recordStr = StringAndByteUtil.intArrayToHexString(results);
            recordStr = recordStr.substring(0, recordStr.length() - 4);
            startLog("recordStr：", recordStr);
            if (recordStr.length() >= 46) {
                String lastStr = "交易序号：" + getInteger(recordStr.substring(0, 4), 16) + "\n"
                        + "交易金额：" + getInteger(recordStr.substring(10, 18), 16) + "\n"
                        + "交易类型：" + getInteger(recordStr.substring(18, 20), 16) + "\n"
                        + "交易终端编号：" + getInteger(recordStr.substring(20, 32), 16) + "\n"
                        + "交易日期：" + getInteger(recordStr.substring(32, 40), 16) + "\n"
                        + "交易时间：" + getInteger(recordStr.substring(40, 46), 16);
                startLog("lastStr：", lastStr);
                mRecords += "\n" + lastStr + "\n";
            }
        }
    }

    private String getInteger(String code, int radix) {
        return Integer.parseInt(code, radix) + "";
    }

    private boolean isSucceed(int[] result) {
        if (result != null && result.length >= 2 && result[result.length - 2] == 0x90 && result[result.length - 1] == 0x00) {
            return true;
        }
        return false;
    }

    private void getFinallyCodeTC(int[] results) {
        if (results != null && results.length >= 2 && results[results.length - 2] == 0x90 && results[results.length - 1] == 0x00) {
            mCode = StringAndByteUtil.intArrayToHexString(results);
            mCode = mCode.substring(0, mCode.length() - 4);
        }
    }

    /**
     * 进行网络请求
     *
     * @param httpUrl
     * @param msgFlg
     */
    private void startHttp(String httpUrl, int msgFlg) {
        httpUrl = httpUrl + TYPE;
        startLog((count + 1) + "：" + "secondUrl: ", httpUrl);
        startRequest(httpUrl, msgFlg);
    }

    /**
     * 拼接第一次请求借口
     *
     * @return
     */
    private String getFirstRequest() {
        return FIRSTREQUESTSTR + setSeid();
    }

    /**
     * 拼接seid
     *
     * @return
     */
    private String setSeid() {
        return SEID_STR + seid;
    }

    @Override
    public void requestJsonOnSucceed(String json, int msgFlag) {
        super.requestJsonOnSucceed(json, msgFlag);
        startLog("json：", json);
        switch (msgFlag) {
            case 1:
                goToNext(json);
                break;
        }
    }

    @Override
    public void requestJsonOnError(int msgFlag) {
        super.requestJsonOnError(msgFlag);
        Log.d(TAG, "requestJsonOnError: ");
        mHandler.sendEmptyMessage(HANDLER_WHAT7);
    }

    @Override
    public void requestJsonOnLocalError(int msgFlag) {
        super.requestJsonOnLocalError(msgFlag);
        Log.d(TAG, "requestJsonOnLocalError: ");
        mHandler.sendEmptyMessage(HANDLER_WHAT8);
    }

    private void goToNext(String json) {
        apduSum = 0;
        count++;
        lastData = "";
        lastApduSw = new int[2];
        Log.d(TAG, count + "：" + "requestJsonOnSucceed: " + json);
        int[] result = new int[0];
        ApduEntity apduEntity = getTByJsonString(json, ApduEntity.class);
        if (apduEntity != null && apduEntity.getApduList() != null && apduEntity.getApduList().size() != 0) {
            int removeCount = 0;
            for (int i = 0; i < apduEntity.getApduList().size(); i++) {
                String lastApdu = apduEntity.getApduList().get(i);
                result = ApduUtil.apdu(m_api_msg, StringAndByteUtil.getInt(lastApdu));
                logIntArray(StringAndByteUtil.getInt(lastApdu), count + "：" + "条数：" + (i + 1) + "参数1：");
                if (result != null) {
                    logIntArray(result, count + "：" + "条数：" + (i + 1) + "结果1：");
                }
                if (is0x61BL(result)) {
                    secondApdu[secondApdu.length - 1] = result[result.length - 1];
                    logIntArray(secondApdu, count + "：" + "条数：" + (i + 1) + "参数2：");
                    result = ApduUtil.apdu(m_api_msg, secondApdu);
                    result = is0x61(result);
                    if (result != null) {
                        logIntArray(result, count + "：" + "条数：" + (i + 1) + "结果2：");
                    }
                }
                if (is0x6c(result)) {
                    int[] params = StringAndByteUtil.getInt(lastApdu);
                    params[params.length - 1] = result[result.length - 1];
                    logIntArray(params, count + "：" + "条数：" + (i + 1) + " 6c参数：");
                    result = ApduUtil.apdu(m_api_msg, params);
                    if (result != null) {
                        logIntArray(result, count + "：" + "条数：" + (i + 1) + "6c结果：");
                    }
                }
                lastData = StringAndByteUtil.intArrayToHexString(getResultData(result, removeCount));
                mLastApdu = apduEntity.getApduList().get(i);
                if (result.length >= 2 && result[result.length - 2] == 0x90 && result[result.length - 1] == 0x00) {
                    apduSum++;
                } else {
                    break;
                }
            }
            if (result.length >= 2) {
                lastApduSw[0] = result[result.length - 2];
                lastApduSw[1] = result[result.length - 1];
                startLog("mLastApdu：", mLastApdu);
                String url1 = URL + LASTAPDUSW + StringAndByteUtil.intArrayToHexString(lastApduSw)
                        + LASTDATA + lastData
                        + APDUNUM + apduSum
                        + LASTAPDU + mLastApdu
                        + setSeid();
                startHttp(url1, 1);
            } else {
                mHandler.sendEmptyMessage(HANDLER_WHAT9);
                Log.d(TAG, "请求结果为空！");
            }
        } else {
            if (apduEntity.isIsOk()) {
                startLog("请求状态：", "请求结束！");
                if (requestType == REQUEST_TYPE_KEYI) {
                    requestType = REQUEST_TYPE_RECHARGE;
                    toRecharge(URL_TYPE_PERSONALIZE);
                }
            } else {
                startLog("请求状态：", "请求失败！");
            }
            if (requestType != REQUEST_TYPE_KEYI) {
                Message message = new Message();
                message.what = HANDLER_WHAT1;
                message.obj = apduEntity.isIsOk();
                mHandler.sendMessage(message);
            }
        }
    }

    private void getRequestType(boolean isOk) {
        switch (requestType) {
            case REQUEST_TYPE_CREATE://创建ssd
                if (isOk) {
                    setTextShow(getString(R.string.createSucceed));
                } else {
                    setTextShow(getString(R.string.createErrorForHttp));
                }
                break;
            case REQUEST_TYPE_DOWNLOAD://下载apdu
                if (isOk) {
                    setTextShow(getString(R.string.downloadSucceed));
                } else {
                    setTextShow(getString(R.string.downloadErrorForHttp));
                }
                break;
            case REQUEST_TYPE_READ:
                readTextShow();
                break;
            case REQUEST_TYPE_RECHARGE://充值
                if (isOk) {
                    setTextShow(getString(R.string.rechargeSucceed));
                } else {
                    setTextShow(getString(R.string.rechargeErrorForHttp));
                }
                break;
            case REQUEST_TYPE_KEYI://可疑记录
                if (isOk) {
                    setTextShow(getString(R.string.keyiSucceed));
                } else {
                    setTextShow(getString(R.string.keyiErrorForHttp));
                }
                break;
        }
    }

    private boolean is0x61BL(int[] result) {
        if (result.length >= 2 && result[result.length - 2] == 0x61) {
            return true;
        }
        return false;
    }

    private int[] is0x61(int[] result) {
        if (result.length >= 2 && result[result.length - 2] == 0x61) {
            result = nextResult(result);
        }
        return result;
    }

    private int[] nextResult(int[] result) {
        secondApdu[secondApdu.length - 1] = result[result.length - 1];
        int[] nextResult = ApduUtil.apdu(m_api_msg, secondApdu);
        if (nextResult != null) {
            logIntArray(nextResult, "第二次请求结果：");
        } else {
            startLog("结果：", "为空！");
        }
        return nextResult;
    }

    private boolean is0x6c(int[] result) {
        if (result[result.length - 2] == 0x6c) {
            return true;
        }
        return false;
    }

    private int[] getResultData(int[] data, int removeCount) {
        if (data.length >= removeCount) {
            int[] datas = new int[data.length - removeCount];
            for (int i = 0; i < datas.length; i++) {
                datas[i] = data[i];
            }
            return datas;
        }
        return new int[0];
    }

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case HANDLER_WHAT1:
                    boolean isOk = (boolean) msg.obj;
                    getRequestType(isOk);
                    break;
                case HANDLER_WHAT2:
                    toCreateSSD();
                    break;
                case HANDLER_WHAT3:
                    downloadApduTC();
                    break;
                case HANDLER_WHAT4:
                    requestType = REQUEST_TYPE_READ;
                    getTCCode();
                    break;
                case HANDLER_WHAT5:
                    getRechargeNum();
                    if (mChargeCount.equals("")) {
                        startToast(getString(R.string.rechargeNum));
                        setTextShow(getString(R.string.rechargeNum));
                        return;
                    }
                    toKEYI();
                    break;
                case HANDLER_WHAT7:
                    getRequestType(false);
                    break;
                case HANDLER_WHAT8:
                    setTextShow(getString(R.string.requestErrorForLocal));
                    break;
                case HANDLER_WHAT9:
                    setTextShow(getString(R.string.apduError) + "\n" + "LasetApdu：" + mLastApdu);
                    break;
            }
        }
    };
}
